using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ALib;
using ALib.Data.CSVOperation;
using ALib.Data.IO;
using TradingPlatform.IB.Operations;

namespace TradingPlatform.IB.Utility
{
    class TradingKernel_SaveContractDetails : TradingKernel
    {
        private InteractiverBrokers _interactiverBrokers;

        public TradingKernel_SaveContractDetails() : base("InteractiveBrokers_RetrieveContractDetails")
        {
        }

        public override void ConnectTradingApi()
        {
            _interactiverBrokers = new InteractiverBrokers(TradingComm);
            string connectReply = _interactiverBrokers.Connect();
            DisplayStatus(connectReply);
        }

        protected override void InitToStart()
        {
            Dictionary<string, string[]> tickerList = new Dictionary<string, string[]>();

            // Generate ticker list.
            foreach (string tickerName in _tickerInfoDb.TickerNameList)
            {
                string exchange = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.exchange);
                string secType = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.secType);
                string symbol = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.symbol);
                string currency = _tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.currency);

                DateTime thisMonth = DateTimeConverter.ToDate(DateTime.Now.ToString("yyyyMM") + "01");
                for (int i = 0; i < 24; i++)
                {
                    string expiry = thisMonth.AddMonths(i).ToString("yyyyMM");
                    
                    string tempTickerName = TickerNameAndId.ToTickerName(exchange, secType, symbol, expiry, currency);
                    if (!tickerList.ContainsKey(tempTickerName))
                    {
                        tickerList.Add(tempTickerName, new string[] { exchange, secType, symbol, expiry, currency });
                    }
                }
            }

            // Request contract details.
            foreach (KeyValuePair<string, string[]> tickerName_TickerInfo in tickerList)
            {
                string exchange = tickerName_TickerInfo.Value[0];
                string secType = tickerName_TickerInfo.Value[1];
                string symbol = tickerName_TickerInfo.Value[2];
                string expiry = tickerName_TickerInfo.Value[3];
                string currency = tickerName_TickerInfo.Value[4];
                _interactiverBrokers.ContractDetails.RequestContractDetails(exchange, secType, symbol, expiry, currency);
            }
        }

        protected override void Timer0_Process()
        {
            _timer0.Stop();

            string savePath = string.Format(@"Log\ContractDetails\{0}", DateTime.Now.ToString(DateTimeFormatType.Simple));

            SaveNewTickerInfo(savePath);
            SaveContractDetails(savePath);
            CheckTradingHours(savePath);
            DisplayStatus(string.Format(@"Saved to [{0}]", savePath));

            // Display error messages.
            foreach (string errorMessage in _interactiverBrokers.ErrorMessageList)
            {
                DisplayErrorMessage(errorMessage);
            }
            _interactiverBrokers.ErrorMessageList.Clear();
        }

        protected override void Timer1_Process()
        {
            //throw new System.NotImplementedException();
        }

        protected override void Timer2_Process()
        {
            //throw new System.NotImplementedException();
        }

        protected override void Timer3_Process()
        {
            //throw new System.NotImplementedException();
        }

        protected override void RequestMarketData()
        {
            throw new System.NotImplementedException();
        }

        protected override void SendOrders(List<string> orders)
        {
            throw new System.NotImplementedException();
        }

        public override void Dispose()
        {
            if (_interactiverBrokers != null)
            {
                _interactiverBrokers.Disconnect();
                _interactiverBrokers.Dispose();
            }
        }

        protected override SortedList<string, string> GetStrategyTickerNameList(List<string> tickerNameList)
        {
            throw new System.NotImplementedException();
        }

        private void SaveNewTickerInfo(string savePath)
        {
            List<string> contractInfoList = new List<string>();
            contractInfoList.Add(@"//tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex, exchange, secType, symbol, expiry, currency,tradingHours,strategySymbol, strategyDiscreption, strategyCurrency, strategyPointValue, strategyMinMove, strategyLotSize,strategyCommissionOnRate, strategyCommissinPerShareInXxx, strategyMinCommissionInXxx, strategyMaxCommissionInXxx, strategyStampDutyRate, strategySlippagePoints");

            foreach (KeyValuePair<string, SortedList<ContractDetailsItemType, string>> tickerName_ContractDetails in _interactiverBrokers.ContractDetails._result)
            {
                string tickerName = tickerName_ContractDetails.Key;
                if (tickerName_ContractDetails.Value.Count > 0)
                {
                    string[] tickerNameItems = tickerName.Split(new char[] { '@' });
                    string exchange = tickerNameItems[0];
                    string secType = tickerNameItems[1];
                    string symbol = tickerNameItems[2];
                    string expiry = tickerNameItems[3];
                    string currency = tickerNameItems[4];

                    string tradingHours = tickerName_ContractDetails.Value[ContractDetailsItemType.tradingHours].Replace(",", "&");
                    string minMove = tickerName_ContractDetails.Value[ContractDetailsItemType.minTick];

                    foreach (string originalTickerName in _tickerInfoDb.TickerNameList)
                    {
                        string[] originalTickerNameItems = originalTickerName.Split(new char[] { '@' });
                        string originalExchange = originalTickerNameItems[0];
                        string originalSecType = originalTickerNameItems[1];
                        string originalSymbol = originalTickerNameItems[2];
                        string originalExpiry = originalTickerNameItems[3];
                        string originalCurrency = originalTickerNameItems[4];

                        if (exchange == originalExchange && secType == originalSecType && symbol == originalSymbol && currency == originalCurrency)
                        {
                            string tickerInfoString = string.Format(
                                @"{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19}",
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.tradingPlatformTimeZoneIndex),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.exchangeTimeZoneIndex),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.exchange),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.secType),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.symbol),
                                expiry, //_tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.expiry),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.currency),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.tradingHours),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategySymbol),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyDiscreption),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyCurrency),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyPointValue),
                                minMove, //_tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyMinMove),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyLotSize),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyCommissionOnRate),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyCommissinPerShareInXxx),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyMinCommissionInXxx),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyMaxCommissionInXxx),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategyStampDutyRate),
                                _tickerInfoDb.GetTickerInfoItem(originalTickerName, TickerInfoItemType.strategySlippagePoints)
                                );
                            GoodValue.Assert(!contractInfoList.Contains(tickerInfoString));
                            contractInfoList.Add(tickerInfoString);
                        }
                    }
                }
            }

            FileInfo outputFile = new FileInfo(savePath + @"\NewTickerInfo.csv");
            FilesIO.ToOneFile(contractInfoList, outputFile);
        }

        private void SaveContractDetails(string savePath)
        {
            List<string> contractInfoList = new List<string>();
            contractInfoList.Add(@"//exchange, secType, symbol, expiry, currency, tradingHours, minMove");
            foreach (KeyValuePair<string, SortedList<ContractDetailsItemType, string>> tickerName_ContractDetails in _interactiverBrokers.ContractDetails._result)
            {
                string tickerName = tickerName_ContractDetails.Key;
                if (tickerName_ContractDetails.Value.Count > 0)
                {
                    string[] tickerNameItems = tickerName.Split(new char[] { '@' });
                    string exchange = tickerNameItems[0];
                    string secType = tickerNameItems[1];
                    string symbol = tickerNameItems[2];
                    string expiry = tickerNameItems[3];
                    string currency = tickerNameItems[4];

                    string tradingHours = tickerName_ContractDetails.Value[ContractDetailsItemType.tradingHours].Replace(",", "&").Replace("-", "00-").Replace("&", "00&").Replace(";", "00;") + "00";
                    string minMove = tickerName_ContractDetails.Value[ContractDetailsItemType.minTick];
                    string tickerInfoString = string.Format(@"{0},{1},{2},{3},{4},{5},{6}", exchange, secType, symbol, expiry, currency, tradingHours, minMove);

                    contractInfoList.Add(tickerInfoString);
                }
            }
            FilesIO.ToOneFile(contractInfoList, new FileInfo(savePath + @"\ContractDetails.csv"));
        }

        private void CheckTradingHours(string savePath)
        {
            TickerInfoDb tickerInfoDb = new TickerInfoDb(new FileInfo(savePath + @"\NewTickerInfo.csv"));

            List<string[]> contractDetailsRecords = CSVEditor.Open(savePath + @"\ContractDetails.csv");

            List<string> result = new List<string>();

            foreach (string[] contractDetailsRecord in contractDetailsRecords)
            {
                //KSE,FUT,K200,201106,KRW,20110111:090000-151500;20110112:090000-151500,0.05
                string tickerName = TickerNameAndId.ToTickerName(contractDetailsRecord[0], contractDetailsRecord[1], contractDetailsRecord[2], contractDetailsRecord[3], contractDetailsRecord[4]);
                string newTradingHours1 = contractDetailsRecord[5];
                string newTradingHours2 = newTradingHours1.Split(new char[] { ';', ':' }, StringSplitOptions.RemoveEmptyEntries)[newTradingHours1.Split(new char[] { ';', ':' }).Length - 1];
                string oldTradingHours = tickerInfoDb.GetTickerInfoItem(tickerName, TickerInfoItemType.tradingHours);

                if (newTradingHours2.IndexOf(oldTradingHours) < 0)
                {
                    string warning = string.Format(@"[Warning],{0},{1},{2}", tickerName, oldTradingHours, newTradingHours1);
                    result.Add(warning);
                    DisplayStatus(warning);
                }
            }

            FilesIO.ToOneFile(result, new FileInfo(savePath + @"\TradingHoursWarning.txt"));
        }
    }
}
